// Own header
#include "sensormanager.h"

// Qt includes
#include <QByteArray>
#include <QDebug>
#include <QList>

// SensorGallery includes
#include "readingvaluemodel.h"
#include "sensormodel.h"

// Constants
const QList<QByteArray> DummySensorTypes = QList<QByteArray>()
    << "DummySensor1"
    << "DummySensor2"
    << "DummySensor3";


/*!
  \class SensorManager
  \brief Class for managing the sensors and the corresponding data models.
*/


/*!
  Constructor.
*/
SensorManager::SensorManager(QObject *parent /* = 0 */)
    : QObject(parent),
      m_currentSensor(0),
      m_sensorModel(0),
      m_readingValueModel(0),
      m_dataRateToSet(0)
{
    m_sensorModel = new SensorModel(this);
    populateSensorModel();

    m_readingValueModel = new ReadingValueModel(this);

    connect(&m_timer, SIGNAL(timeout()), this, SLOT(setSensorDataRate()));
}


/*!
  Destructor.
*/
SensorManager::~SensorManager()
{
    if (m_currentSensor) {
        m_currentSensor->stop();
    }
}


/*!
  Returns the current sensor.
*/
QSensor *SensorManager::currentSensor() const
{
    return m_currentSensor;
}


/*!
  Returns the sensor model.
*/
SensorModel *SensorManager::sensorModel() const
{
    return m_sensorModel;
}


/*!
  Returns the reading value model.
*/
ReadingValueModel *SensorManager::readingValueModel() const
{
    return m_readingValueModel;
}

/*!
  Returns the sensor type of the current sensor.
*/
QString SensorManager::sensorType() const
{
    if (m_currentSensor) {
        return QString(m_currentSensor->type());
    }

#if defined(Q_OS_WIN) && !defined(Q_WS_SIMULATOR)
    return QString("DummySensorType");
#endif

    return QString();
}


/*!
  Returns the sensor data rate.
*/
int SensorManager::sensorDataRate() const
{
    if (m_currentSensor) {
        return m_currentSensor->dataRate();
    }

    return 0;
}


/*!
  Sets the current sensor according to \a type.
*/
bool SensorManager::setSensorType(const QString &type)
{
    QByteArray sensorType = m_sensorModel->typeByString(type);

    if (sensorType.isNull() || sensorType.isEmpty()) {
        qDebug() << "No such sensor!";
        return false;
    }

    qDebug() << "setSensorType():" << sensorType;

    if (m_currentSensor) {
        qDebug() << "Stopping and deleting the previous sensor instance.";
        m_currentSensor->stop();
        m_readingValueModel->setSensor(0);
        delete m_currentSensor;
        m_currentSensor = 0;
    }

#if !defined(Q_OS_WIN) || defined(Q_WS_SIMULATOR)
    m_currentSensor = new QSensor(sensorType, this);
#endif

    // The reading value model will try to start the sensor.
    bool success = m_readingValueModel->setSensor(m_currentSensor);

    if (success) {
        emit sensorTypeChanged(type);
    }

    return success;
}


/*!
  Sets the sensor data rate to \a dataRate.
*/
bool SensorManager::setSensorDataRate(int dataRate)
{
    if (!m_currentSensor || dataRate < 0) {
        return false;
    }

    if (m_timer.isActive()) {
        m_timer.stop();
    }

    // Start the timer to set the data rate in 1 second.
    m_dataRateToSet = dataRate;
    m_timer.start(1000);
    m_timer.setSingleShot(true);
    return true;
}


/*!
  Populates the sensor model.
*/
void SensorManager::populateSensorModel()
{
#if defined(Q_OS_WIN) && !defined(Q_WS_SIMULATOR)
    m_sensorModel->setSensorTypes(DummySensorTypes);
#else
    m_sensorModel->setSensorTypes(QSensor::sensorTypes());
#endif
}


/*!
  Sets the sensor data rate to value defined in the member variable
  m_dataRateToSet.
*/
void SensorManager::setSensorDataRate()
{
    qDebug() << "Trying to set the sensor rate to " << m_dataRateToSet;

    if (m_currentSensor && m_dataRateToSet >= 0) {
        // Stop the sensor before setting the data rate to be on the safe side.
        m_currentSensor->stop();
        m_currentSensor->setDataRate(m_dataRateToSet);
        m_currentSensor->start();
        emit sensorDataRateChanged(m_currentSensor->dataRate());
    }
}


// End of file.
